package com.jijunpeng.javafx.cipher;

import cn.hutool.core.util.ArrayUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import com.jijunpeng.javafx.cipher.controller.api.BaseController;
import com.jijunpeng.javafx.cipher.persistence.PersistenceJson;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * @author jijunpeng
 */
@Slf4j
public class CipherToolApplication extends Application {

    private static final JSONObject PERSISTENCE_JSON = new JSONObject();
    private static final List<BaseController> CONTROLLER_LIST = new ArrayList<>();
    private static final File PERSISTENCE_JSON_FILE = new File(System.getProperty("user.home") + "/.cipherTool/persistence.json");

    public synchronized static void addController(BaseController controller) {
        CONTROLLER_LIST.add(controller);
    }

    static {

        if (!PERSISTENCE_JSON_FILE.exists()) {
            if (!PERSISTENCE_JSON_FILE.getParentFile().exists()) {
                if (PERSISTENCE_JSON_FILE.getParentFile().mkdirs()) {
                    log.error("不能创建配置文件的文件夹");
                }
            }
            try {
                PERSISTENCE_JSON_FILE.createNewFile();
            } catch (IOException e) {
                log.error("创建配置文件出错 ");
            }
        }

        final StringBuilder sb = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new FileReader(PERSISTENCE_JSON_FILE))) {
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line).append("\n");
            }
            JSONObject fileConfig = JSONObject.parseObject(sb.toString());
            if (fileConfig != null) {
                PERSISTENCE_JSON.putAll(fileConfig.getInnerMap());
            }
        } catch (IOException e) {
            log.error("初始化失败。e:", e);
        }
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("/fxml/main.fxml"));
        Properties properties = new Properties();

        properties.load(this.getClass().getResourceAsStream("/project.properties"));
        primaryStage.setTitle("Cipher Tool v" + properties.get("project.version"));
        primaryStage.getIcons().add(new Image(getClass().getResourceAsStream("/img/ic_launcher.png")));
        primaryStage.setScene(new Scene(root, 800, 480));
        primaryStage.setMinWidth(1200);
        primaryStage.setMinHeight(800);
        primaryStage.show();

        primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
            @SneakyThrows
            @Override
            public void handle(WindowEvent event) {
                log.info("监听到窗口关闭");
                PERSISTENCE_JSON.clear();
                for (BaseController baseController : CONTROLLER_LIST) {
                    JSONObject controllerPersistenceInfo = baseController.persistWidgets();
                    Map<String, Object> pathAndValueMap = JSONPath.paths(controllerPersistenceInfo);
                    for (String path : pathAndValueMap.keySet()) {
                        JSONPath.set(PERSISTENCE_JSON, path, pathAndValueMap.get(path));
                    }
                }
                try (BufferedWriter writer = new BufferedWriter(new FileWriter(PERSISTENCE_JSON_FILE))) {
                    String jsonString = JSONObject.toJSONString(PERSISTENCE_JSON, true);
                    writer.write(jsonString);
                    writer.flush();
                }

                log.info("窗口完全关闭");
            }
        });
    }

    public synchronized static JSONObject readConfig(BaseController controller) {
        PersistenceJson[] classPersistenceJsons = controller.getClass().getDeclaredAnnotationsByType(PersistenceJson.class);
        if (ArrayUtil.isEmpty(classPersistenceJsons)) {
            return null;
        }
        PersistenceJson classPersistenceJson = classPersistenceJsons[0];
        String controllerConfigKey = classPersistenceJson.path().replaceFirst("\\$\\.", "");
        Object eval = JSONPath.eval(PERSISTENCE_JSON, classPersistenceJson.path());
        if (eval == null) {
            return null;
        }
        JSONObject jsonObject = new JSONObject();
        JSONPath.set(jsonObject, classPersistenceJson.path(), eval);
        return jsonObject;
    }

    public static void main(String[] args) {
        launch(args);
    }
}
